package jmine.tec.hydra.repository;

import static jmine.tec.hydra.domain.enumx.HydraScriptPurposeIdentifier.HYDRA_DECODING;
import static jmine.tec.hydra.domain.enumx.HydraScriptPurposeIdentifier.HYDRA_ENCODING;
import static jmine.tec.hydra.domain.enumx.HydraScriptPurposeIdentifier.HYDRA_FILTERING;
import static jmine.tec.hydra.domain.enumx.HydraScriptPurposeIdentifier.HYDRA_RECEIVE_ACTIVATION;
import static jmine.tec.hydra.domain.enumx.HydraScriptPurposeIdentifier.HYDRA_RENDERING;
import static jmine.tec.hydra.domain.enumx.HydraScriptPurposeIdentifier.HYDRA_SEND_ACTIVATION;
import static jmine.tec.hydra.domain.enumx.HydraScriptPurposeIdentifier.MESSAGE_DISPATCH;
import jmine.tec.hydra.domain.enumx.HydraScriptPurposeIdentifier;
import jmine.tec.hydra.script.impl.DecodeScriptContextImpl;
import jmine.tec.hydra.script.impl.DispatchScriptContextImpl;
import jmine.tec.hydra.script.impl.EncodeScriptContextImpl;
import jmine.tec.hydra.script.impl.FilterScriptContextImpl;
import jmine.tec.hydra.script.impl.ReceiveActivationScriptContextImpl;
import jmine.tec.hydra.script.impl.RenderMessageScriptContextImpl;
import jmine.tec.hydra.script.impl.SendActivationScriptContextImpl;
import jmine.tec.script.ScriptExecutionContext;
import jmine.tec.script.impl.beanshell.repository.BeanshellSupport;
import jmine.tec.script.impl.velocity.repository.VelocitySupport;
import jmine.tec.script.persistent.repository.ScriptPurposeBuilder;
import jmine.tec.script.persistent.repository.TransientScriptRepository;

/**
 * Classe utilitária para configurar um TransientScriptRepository com suporte adequado a execução de scripts Hydra.
 * 
 * @author lundberg
 */
public final class HydraSupport {

    private static final String BSH_TYPE = "SCRIPT-BSH";

    private static final String INIT_TEMPLATE = "postscript/init/%.bsh";

    /**
     * Construtor vazio
     */
    private HydraSupport() {
        // OK
    }

    /**
     * Adiciona suporte a execução de scripts Hydra.
     * 
     * @param repository repository
     */
    public static void addTo(TransientScriptRepository repository) {
        BeanshellSupport.addTo(repository);
        VelocitySupport.addTo(repository);

        addPurpose(repository, HYDRA_SEND_ACTIVATION, SendActivationScriptContextImpl.class);
        addPurpose(repository, HYDRA_RECEIVE_ACTIVATION, ReceiveActivationScriptContextImpl.class);
        addPurpose(repository, HYDRA_DECODING, DecodeScriptContextImpl.class);
        addPurpose(repository, HYDRA_ENCODING, EncodeScriptContextImpl.class);
        addPurpose(repository, HYDRA_RENDERING, RenderMessageScriptContextImpl.class);
        addPurpose(repository, HYDRA_FILTERING, FilterScriptContextImpl.class);
        addPurpose(repository, MESSAGE_DISPATCH, DispatchScriptContextImpl.class);
    }

    private static void addPurpose(TransientScriptRepository repository, HydraScriptPurposeIdentifier identifier,
            Class<? extends ScriptExecutionContext<?>> context) {
        ScriptPurposeBuilder purpose = ScriptPurposeBuilder.aPurpose().withEnumIdentifier(identifier);
        purpose = purpose.comContextoDeExecucao(context);
        purpose = purpose.comInitScript(repository.loadScript(BSH_TYPE, String.format(INIT_TEMPLATE, identifier.name())));
        repository.addPurpose(purpose.build());
    }
}
